package com.pcbly.web.components.utils.provider;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import org.apache.commons.collections.EnumerationUtils;
import org.apache.commons.lang.BooleanUtils;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.LocaleProvider;
import com.opensymphony.xwork2.TextProviderSupport;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.opensymphony.xwork2.util.ValueStack;
import com.pcbly.web.components.utils.LocaleUtils;
import com.pcbly.web.components.utils.theme.Theme;

@SuppressWarnings("unchecked")
public class OfficeTextProvider extends TextProviderSupport {
	private static final boolean showI18nKeys = BooleanUtils.toBoolean(System
			.getProperty("showI18nKeys"));
	protected Class clazz;
	protected LocaleProvider provider;
	protected ResourceBundle bundle;
	protected boolean officeI18nTextBundlesLoaded;
	protected Map officeI18nTextBundles;
	protected boolean themeListLoaded;
	protected List themeList;

	public OfficeTextProvider(Class clazz, LocaleProvider provider) {
		super(clazz, provider);
		officeI18nTextBundlesLoaded = false;
		themeListLoaded = false;
		this.clazz = clazz;
		this.provider = provider;
	}

	public OfficeTextProvider(ResourceBundle bundle, LocaleProvider provider) {
		super(bundle, provider);
		officeI18nTextBundlesLoaded = false;
		themeListLoaded = false;
		this.bundle = bundle;
		this.provider = provider;
	}

	public String getText(String key, String defaultValue, String args[]) {
		return doGetText(key, defaultValue, args, null);
	}

	public String getText(String key, String defaultValue, List args) {
		Object argsArray[] = args == null
				|| args.equals(Collections.emptyList()) ? null : args.toArray();
		return doGetText(key, defaultValue, argsArray, null);
	}

	public String getText(String key, String defaultValue, List args,
			ValueStack stack) {
		Object argsArray[] = args == null ? null : args.toArray();
		return doGetText(key, defaultValue, argsArray, stack);
	}

	public String getText(String key, String defaultValue, String args[],
			ValueStack stack) {
		return doGetText(key, defaultValue, args, stack);
	}

	protected String doGetText(String key, String defaultValue, Object args[],
			ValueStack stack) {
		Locale locale;
		ValueStack theStack;
		List candidateLocales;
		Iterator i$;
		if (showI18nKeys)
			return key;
		if (stack == null)
			locale = getLocale();
		else
			locale = (Locale) stack.getContext().get(
					"com.opensymphony.xwork2.ActionContext.locale");
		if (locale == null)
			locale = getLocale();
		theStack = stack != null ? stack : ActionContext.getContext()
				.getValueStack();
		candidateLocales = LocaleUtils.getCandidateLocales(locale);
		if (themeList.isEmpty())
			return null;
		for (i$ = themeList.iterator(); i$.hasNext();) {
			Theme theme = (Theme) i$.next();
			for (Iterator it = candidateLocales.iterator(); it.hasNext();) {
				Locale candidateLocale = (Locale) it.next();
				ResourceBundle overrides = theme
						.getResourceBundleOverride(candidateLocale);
				if (overrides != null) {
					List keyList = EnumerationUtils.toList(overrides.getKeys());
					if (keyList.contains(key)) {
						return LocalizedTextUtil.findText(overrides, key,
								locale, defaultValue, args, theStack);
					}
				}
			}
		}
		List officeI18nTextCandidateLocales = new ArrayList(candidateLocales);
		officeI18nTextCandidateLocales.addAll(LocaleUtils
				.getCandidateLocales(Locale.getDefault()));
		for (Iterator it = officeI18nTextCandidateLocales.iterator(); it
				.hasNext();) {
			Locale candidateLocale = (Locale) it.next();
			OfficeI18nTextResourceBundle bundle = getOfficeI18nTextBundle(candidateLocale);
			if (bundle != null && bundle.keySet.contains(key))
				return LocalizedTextUtil.findText(bundle, key, locale,
						defaultValue, args, theStack);
		}
		if (clazz != null)
			return LocalizedTextUtil.findText(clazz, key, locale, defaultValue,
					args, theStack);
		else
			return LocalizedTextUtil.findText(this.bundle, key, locale,
					defaultValue, args, theStack);
	}

	protected Locale getLocale() {
		return provider.getLocale();
	}

	protected OfficeI18nTextResourceBundle getOfficeI18nTextBundle(Locale locale) {

		return (OfficeI18nTextResourceBundle) officeI18nTextBundles.get(locale);
	}
}
